package org.springblade.tms.module.userinfo.base;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.logging.log4j.util.Strings;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.tms.global.entity.TimeInterval;
import org.springblade.tms.global.enums.ApprovalStatusEnum;
import org.springblade.tms.global.enums.SapActionEnum;
import org.springblade.tms.global.enums.TableNameEnum;
import org.springblade.tms.global.enums.UserTypeEnum;
import org.springblade.tms.global.exception.CommonException;
import org.springblade.tms.module.approval.entity.TMApproval;
import org.springblade.tms.module.approval.service.IApprovalService;
import org.springblade.tms.module.car.entity.TMCar;
import org.springblade.tms.module.car.service.ICarService;
import org.springblade.tms.module.carriercarrelation.entity.TMCarrierCarRelation;
import org.springblade.tms.module.carriercarrelation.service.ICarrierCarRelationService;
import org.springblade.tms.module.carrierdriverrelation.entity.TMCarrierDriverRelation;
import org.springblade.tms.module.carrierdriverrelation.service.ICarrierDriverRelationService;
import org.springblade.tms.module.carriersupercargorelation.entity.TMCarrierSupercargoRelation;
import org.springblade.tms.module.carriersupercargorelation.service.ICarrierSupercargoRelationService;
import org.springblade.tms.module.carriertankrelation.entity.TMCarrierTankRelation;
import org.springblade.tms.module.carriertankrelation.service.ICarrierTankRelationService;
import org.springblade.tms.module.sap.base.SapRequestService;
import org.springblade.tms.module.supercargoinfo.entity.TMSupercargoInfo;
import org.springblade.tms.module.supercargoinfo.service.ISupercargoInfoService;
import org.springblade.tms.module.supercargoinfo.vo.TMSupercargoInfoVO;
import org.springblade.tms.module.tank.entity.TMTankTank;
import org.springblade.tms.module.tank.service.ITankTankService;
import org.springblade.tms.module.tank.vo.TMTankTankVO;
import org.springblade.tms.module.userinfo.dto.CarDto;
import org.springblade.tms.module.userinfo.dto.CarrierAuditReq;
import org.springblade.tms.module.userinfo.dto.DriverDto;
import org.springblade.tms.module.userinfo.entity.TMUserInfo;
import org.springblade.tms.module.userinfo.service.IUserInfoService;
import org.springblade.tms.module.userinfo.vo.TMUserInfoVO;
import org.springblade.tms.module.userinfo.vo.UserInfoVo;
import org.springblade.tms.module.userinfo.wrapper.UserInfoWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yr
 * @Date 2022/3/7 10:30
 * @desc 承运商基本信息
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class CarrierManagementService {
	@Resource
	private IUserInfoService userInfoService;
	@Resource
	private IApprovalService approvalService;
	@Resource
	private ICarrierCarRelationService carrierCarRelationService;
	@Resource
	private ICarrierDriverRelationService carrierDriverRelationService;
	@Resource
	private ICarrierSupercargoRelationService carrierSupercargoRelationService;
	@Resource
	private ICarService carService;
	@Resource
	private SapRequestService sapRequestService;
	@Resource
	private ISupercargoInfoService supercargoInfoService;
	@Resource
	private ITankTankService tankTankService;
	@Resource
	private ICarrierTankRelationService carrierTankRelationService;

	/**
	 * @author yr
	 * @Date 2022/3/7 10:30
	 * @desc 承运商基本信息查询
	 */
	public R<IPage<UserInfoVo>> list(TMUserInfoVO userInfo, Query query, TimeInterval timeInterval) {
		//即将到期查询参数
		LocalDateTime expireDate = LocalDateTime.now().plusMonths(1);
		userInfo.setUserType(UserTypeEnum.CARRIER.getValue());
		QueryWrapper<TMUserInfo> queryWrapper = Condition.getQueryWrapper(new TMUserInfo());
		IPage<TMUserInfo> userInfoPage = userInfoService.page(Condition.getPage(query), queryWrapper.lambda()
			.like(userInfo.getName() != null && !userInfo.getName().isEmpty(), TMUserInfo::getName, userInfo.getName())
			.like(userInfo.getPhone() != null && !userInfo.getPhone().isEmpty(), TMUserInfo::getPhone, userInfo.getPhone())
			.like(Strings.isNotBlank(userInfo.getCarrierGroup()), TMUserInfo::getCarrierGroup, userInfo.getCarrierGroup())
			.eq(userInfo.getApprovalStatus() != null && !userInfo.getApprovalStatus().isEmpty(), TMUserInfo::getApprovalStatus, userInfo.getApprovalStatus())
			.eq(TMUserInfo::getUserType, userInfo.getUserType())
			.ge(timeInterval.getStart() != null, TMUserInfo::getCreateTime, timeInterval.getStart())
			.le(timeInterval.getEnd() != null, TMUserInfo::getCreateTime, timeInterval.getEnd())
			//即将到期列表查询
			.and(userInfo.getExpireDate(), tmUserInfoLambdaQueryWrapper -> tmUserInfoLambdaQueryWrapper
				.le(TMUserInfo::getCertificateTransportValidDateEnd, expireDate).or()
				.le(TMUserInfo::getCertificateOperationValidDateEnd, expireDate))
			.orderByDesc(TMUserInfo::getUpdateTime, TMUserInfo::getId));
		userInfoPage.getRecords().forEach(tmUserInfo -> tmUserInfo.setApprovalStatus(ApprovalStatusEnum.getDescriptionByValue(tmUserInfo.getApprovalStatus())));
		//获取审核表的驳回原因
		LinkedList<UserInfoVo> list = new LinkedList<>();
		List<Long> ids = userInfoPage.getRecords().stream().map(TMUserInfo::getId).collect(Collectors.toList());
		List<TMApproval> tmApprovalList = approvalService.lambdaQuery().in(!ids.isEmpty(), TMApproval::getRelationId, ids)
			.apply(ids.isEmpty(), "1=2").list();
		Map<Long, String> remarkMap = tmApprovalList.stream().collect(Collectors.toMap(TMApproval::getRelationId, TMApproval::getRemarkReject));
		for (TMUserInfo record : userInfoPage.getRecords()) {
			UserInfoVo userInfoVo = BeanUtil.copy(record, UserInfoVo.class);
			userInfoVo.setRemarkReject(remarkMap.get(record.getId()));
			list.add(userInfoVo);
		}

		IPage page = userInfoPage;
		page.setRecords(list);
		return R.data(page);
	}

	/**
	 * @author yr
	 * @Date 2022/3/7 10:30
	 * @desc 承运商个人信息查询
	 */
	public R<UserInfoVo> personalInformation() {
		BladeUser user = AuthUtil.getUser();
		TMUserInfo userInfo = new TMUserInfo();
		userInfo.setParentId(user.getUserId());
		TMUserInfo selectOne = userInfoService.getOne(Condition.getQueryWrapper(userInfo));
		UserInfoVo userInfoVo = BeanUtil.copy(selectOne, UserInfoVo.class);
		userInfoVo.setApprovalStatus(ApprovalStatusEnum.getDescriptionByValue(userInfoVo.getApprovalStatus()));
		TMApproval approval = approvalService.lambdaQuery().eq(TMApproval::getRelationId, userInfoVo.getId()).one();
		if (approval != null) {
			userInfoVo.setRemarkReject(approval.getRemarkReject());
		}
		return R.data(userInfoVo);
	}

	/**
	 * @author yr
	 * @Date 2022/3/7 10:30
	 * @desc 承运商个人信息修改
	 */
	public Boolean update(TMUserInfo userInfo) {
		if (Strings.isNotBlank(userInfo.getMailbox())) {
			ArrayList<String> mailboxS = ListUtil.toList(userInfo.getMailbox().split(","));
			mailboxS.forEach(mailbox -> {
				//邮箱校验
				try {
					Validator.validateMatchRegex("(^\\w+((-\\w+)|(\\.\\w+))*@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$)", mailbox, "邮箱校验失败");
				} catch (ValidateException validateException) {
					CommonException.throwCommonException(validateException.getMessage());
				}
			});
		}
		userInfo.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
		TMApproval tmApproval = new TMApproval();
		tmApproval.setRelationId(userInfo.getId());
		TMApproval selectOne = approvalService.getOne(Condition.getQueryWrapper(tmApproval));
		if (selectOne == null) {
			tmApproval.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
			tmApproval.setRelationTableName(TableNameEnum.USER_INFO.value());
			approvalService.save(tmApproval);
		} else {
			selectOne.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
			selectOne.setRemarkReject("");
			selectOne.setRelationTableName(TableNameEnum.USER_INFO.value());
			approvalService.updateById(selectOne);
		}
		boolean updateById = userInfoService.updateById(userInfo);
		if (!updateById) {
			throw CommonException.throwCommonException("修改失败");
		}
		return true;
	}

	/**
	 * @author yr
	 * @Date 2022/3/7 10:30
	 * @desc userinfo审核
	 */
	public R check(List<CarrierAuditReq> carrierAuditReq) {
		if (carrierAuditReq.size() == 1) {
			CarrierAuditReq auditReq = carrierAuditReq.get(0);
			TMUserInfo tmUserInfo = userInfoService.getById(auditReq.getId());
			TMApproval tmApproval = new TMApproval();
			tmApproval.setRelationId(auditReq.getId());
			TMApproval approval = approvalService.getOne(Condition.getQueryWrapper(new TMApproval()).lambda()
				.eq(TMApproval::getRelationId, auditReq.getId()));
			if (auditReq.getPass()) {
				tmUserInfo.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue());
				approval.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue());
			} else {
				tmUserInfo.setApprovalStatus(ApprovalStatusEnum.REJECTED.getValue());
				approval.setApprovalStatus(ApprovalStatusEnum.REJECTED.getValue());
				approval.setRemarkReject(auditReq.getReasonForRejection());
			}
			Boolean update = userInfoService.updateById(tmUserInfo);
			Boolean update1 = approvalService.updateById(approval);
			if (tmUserInfo.getApprovalStatus().equals(ApprovalStatusEnum.PASSED.getValue())) {
				ArrayList<TMUserInfo> tmUserInfos = new ArrayList<>();
				tmUserInfos.add(tmUserInfo);

				R driverMasterData = sapRequestService.driverMasterData(tmUserInfos, SapActionEnum.S.getValue());
				if (driverMasterData.getMsg().equals("操作失败")) {
					throw CommonException.throwCommonException("上报TM失败");
				}
			}
			if (!(update && update1)) {
				throw CommonException.throwCommonException("审核失败，请重新审核");
			}

			return R.success("成功");
		} else {
			List<Long> ids = carrierAuditReq.stream().map(CarrierAuditReq::getId).collect(Collectors.toList());
			List<TMUserInfo> tmUserInfoList = userInfoService.lambdaQuery().in(TMUserInfo::getId, ids).list();
			tmUserInfoList.forEach(userInfo -> userInfo.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue()));
			boolean updateBatchById = userInfoService.updateBatchById(tmUserInfoList);
			List<TMApproval> tmApprovalList = approvalService.lambdaQuery().in(TMApproval::getRelationId, ids).list();
			tmApprovalList.forEach(approval -> approval.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue()));
			boolean batchById = approvalService.updateBatchById(tmApprovalList);
			R driverMasterData = sapRequestService.driverMasterData(tmUserInfoList, SapActionEnum.S.getValue());
			if (driverMasterData.getMsg().equals("操作失败")) {
				throw CommonException.throwCommonException("上报TM失败");
			}
			return R.status(batchById && updateBatchById);
		}
	}

	/**
	 * @param driverDto:
	 * @param query:
	 * @param timeInterval:
	 * @return R<IPage                               <                               TMUserInfoVO>>
	 * @author yr
	 * @description 司机列表查询
	 * @date 2022/3/10 11:25
	 */
	public R<IPage<TMUserInfoVO>> driverList(DriverDto driverDto, Query query, TimeInterval timeInterval) {
		List<TMCarrierDriverRelation> list = carrierDriverRelationService.lambdaQuery()
			.select(TMCarrierDriverRelation::getRelationDriver)
			.eq(TMCarrierDriverRelation::getRelationCarrierNo, driverDto.getCarrierId())
			.list();
		List<Long> driverIds = list.stream().map(TMCarrierDriverRelation::getRelationDriver).collect(Collectors.toList());
		IPage<TMUserInfo> page = userInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(new TMUserInfo()).lambda()
			.like(driverDto.getName() != null && !driverDto.getName().isEmpty(), TMUserInfo::getName, driverDto.getName())
			.like(driverDto.getPhone() != null && !driverDto.getPhone().isEmpty(), TMUserInfo::getPhone, driverDto.getPhone())
			.in(!driverIds.isEmpty(), TMUserInfo::getId, driverIds)
			.ge(timeInterval.getStart() != null, TMUserInfo::getCreateTime, timeInterval.getStart())
			.le(timeInterval.getEnd() != null, TMUserInfo::getCreateTime, timeInterval.getEnd())
			.apply(driverIds.isEmpty(), "1=2"));
		return R.data(UserInfoWrapper.build().pageVO(page));
	}

	/**
	 * @param carDto:
	 * @param query:
	 * @return R<IPage                               <                               TMCar>>
	 * @author yr
	 * @description 车辆列表查询
	 * @date 2022/3/10 13:40
	 */
	public R<IPage<TMCar>> carList(CarDto carDto, Query query) {
		List<TMCarrierCarRelation> list = carrierCarRelationService.lambdaQuery()
			.select(TMCarrierCarRelation::getRelationCarNo)
			.eq(TMCarrierCarRelation::getRelationCarrierNo, carDto.getCarrierId())
			.list();
		List<Long> driverIds = list.stream().map(TMCarrierCarRelation::getRelationCarNo).collect(Collectors.toList());
		TMCar car = carDto.getCar();
		LambdaQueryWrapper<TMCar> tmCarLambdaQueryWrapper = Condition.getQueryWrapper(new TMCar()).lambda()
			.like(car.getCarNo() != null && !car.getCarNo().isEmpty(), TMCar::getCarNo, car.getCarNo())
			.like(car.getBindCarNo() != null && !car.getBindCarNo().isEmpty(), TMCar::getBindCarNo, car.getBindCarNo())
			.eq(car.getCarType() != null && !car.getCarType().isEmpty(), TMCar::getCarType, car.getCarType())
			.eq(car.getTransportGoodsType() != null && !car.getTransportGoodsType().isEmpty(), TMCar::getTransportGoodsType, car.getTransportGoodsType())
			.in(!driverIds.isEmpty(), TMCar::getId, driverIds).apply(driverIds.isEmpty(), "1=2");
		if (carDto.getTimeInterval() != null) {
			tmCarLambdaQueryWrapper.ge(carDto.getTimeInterval().getStart() != null, TMCar::getCreateTime, carDto.getTimeInterval().getStart())
				.le(carDto.getTimeInterval().getEnd() != null, TMCar::getCreateTime, carDto.getTimeInterval().getEnd());
		}
		IPage<TMCar> page = carService.page(Condition.getPage(query), tmCarLambdaQueryWrapper);
		return R.data(page);
	}

	/**
	 * @param tmSupercargoInfo:
	 * @param query:
	 * @param timeInterval:
	 * @return R<IPage                               <                               TMCar>>
	 * @author yr
	 * @description 押运员列表查询
	 * @date 2022/5/7 11:35
	 */
	public R<IPage<TMSupercargoInfo>> escortList(TMSupercargoInfoVO tmSupercargoInfo, Query query, TimeInterval timeInterval) {
		List<TMCarrierSupercargoRelation> list = carrierSupercargoRelationService.lambdaQuery()
			.select(TMCarrierSupercargoRelation::getRelationSupercargoNo)
			.eq(TMCarrierSupercargoRelation::getRelationCarrierNo, tmSupercargoInfo.getCarrierId())
			.list();
		List<Long> driverIds = list.stream().map(TMCarrierSupercargoRelation::getRelationSupercargoNo).collect(Collectors.toList());
		LambdaQueryWrapper<TMSupercargoInfo> tmCarLambdaQueryWrapper = Condition.getQueryWrapper(new TMSupercargoInfo()).lambda()
			.like(Strings.isNotBlank(tmSupercargoInfo.getName()), TMSupercargoInfo::getName, tmSupercargoInfo.getName())
			.like(Strings.isNotBlank(tmSupercargoInfo.getPhone()), TMSupercargoInfo::getPhone, tmSupercargoInfo.getPhone())
			.in(!driverIds.isEmpty(), TMSupercargoInfo::getId, driverIds).apply(driverIds.isEmpty(), "1=2");
		if (timeInterval != null) {
			tmCarLambdaQueryWrapper.ge(timeInterval.getStart() != null, TMSupercargoInfo::getCreateTime, timeInterval.getStart())
				.le(timeInterval.getEnd() != null, TMSupercargoInfo::getCreateTime, timeInterval.getEnd());
		}
		IPage<TMSupercargoInfo> page = supercargoInfoService.page(Condition.getPage(query), tmCarLambdaQueryWrapper);
		return R.data(page);
	}

	/**
	 * @param tankVo:
	 * @param query:
	 * @return R<IPage                               <                               TMTankTank>>
	 * @author yr
	 * @description 坦克罐列表查询
	 * @date 2022/6/2 11:57
	 */
	public R<IPage<TMTankTank>> tankList(TMTankTankVO tankVo, Query query) {
		List<TMCarrierTankRelation> list = carrierTankRelationService.lambdaQuery()
			.select(TMCarrierTankRelation::getRelationTankNo)
			.eq(TMCarrierTankRelation::getRelationCarrierNo, tankVo.getCarrierId())
			.list();
		List<Long> tankIds = list.stream().map(TMCarrierTankRelation::getRelationTankNo).collect(Collectors.toList());
		LambdaQueryWrapper<TMTankTank> tmTankTankLambdaQueryWrapper = Condition.getQueryWrapper(new TMTankTank()).lambda()
			.like(tankVo.getProduct() != null, TMTankTank::getProduct, "%" + tankVo.getProduct() + "%")
			.like(tankVo.getTankNumber() != null, TMTankTank::getTankNumber, tankVo.getTankNumber())
			.in(!tankIds.isEmpty(), TMTankTank::getId, tankIds).apply(tankIds.isEmpty(), "1=2");
		IPage<TMTankTank> page = tankTankService.page(Condition.getPage(query), tmTankTankLambdaQueryWrapper);
		return R.data(page);
	}
}
